# Wave Imports
from waveapi import events
from waveapi import robot
from waveapi import appengine_robot_runner
import logging

# Other Imports
from Forensie import Forensie
from re import sub
	
def OnWaveletSelfAdded(event, wavelet):
	"""
	When Forensie is added to an existing wave, this method posts 
	information to the wave about supported commands and how to use 
	Forensie.
	"""
	foren = Forensie('')
	wavelet.reply("Welcome to Forensie!\n\nThe following are valid commands:\n%s\n\nEach command must be entered in the following format at the beginning of a line, and must begin with the '>>' characters:\n\n>> main-command [sub-command]" % foren.GetCommandDescriptions())

def OnBlipSubmitted(event, wavelet):
	"""
	When a blip is submitted to a wave where Forensie is a participant, 
	this method captures the new input, sends it to a Forensie instance for 
	processing, and in the event that the processing was a success, posts 
	the results to the wave.
	
	If there is already a post authored by Forensie, that post's contents 
	will be replaced by the results obtained (determined by searching the 
	list returned from getChildBlipIds()).
	
	If the processed text was simple hex text, the results will be given a 
	fixed-width font so that it prints properly. In the future, it would be 
	nice to be able to separate such results into columns or a table. This 
	would allow the user to select hex or ascii text only.
	"""
	# Decision engine for processing/posting called here
	mbr = event.blip.text
	foren = Forensie(mbr)
	
	# Get text to post in reply here
	text, status, texttype = foren.ProcessInput()
	if status == 'fail': 
		# Look for an attachment ?
		for e in event.blip.elements:
			if e.type == 'IMAGE':
				print "File properties:\n%s" % e.properties
		return
	
	# Look through all the blips of the parent wavelet to see if we've already posted a translation
	changeTranslation = False
	child_blip_info = getChildBlipIds(event.blip)
	for c in child_blip_info:
		if c[1] == 'forensie@appspot.com':
			if changeTranslation: # Something funky happened. Delete other post.
				wavelet.delete(c[0])
				continue
			changeTranslation = True
			if status == 'success':
				ref = c[0].all() # Get a reference to the entire previous post
				ref.delete() # Delete previous post's contents
				c[0].append(text) # Append to the previous post which is now empty
				r = c[0].all()
				r.clear_annotation("style/fontFamily")
				if texttype == 'hex':
					r.annotate("style/fontFamily", "monospace")
			else:
				# Wasn't able to translate or interpret the post. Delete the old one.
				if len(list(c[0].contributors)) == 1: wavelet.delete(c[0])
				else: print c[0].contributors
	
	# No previous post found
	if not changeTranslation and status == 'success':
		r = event.blip.reply()
		r.append(text)
		r.all().clear_annotation("style/fontFamily")
		if texttype == 'hex':
			# Annotate
			r.all().annotate("style/fontFamily", "monospace")
	
def getChildBlipIds(blip):
	"""
	Loops through the children of blip recursively and returns a list of 
	tuples with information on each child in the form (blip, creator of 
	blip, first 20 characters of text in blip).
	"""
	data = []
	if type(blip) == unicode: return [('Unicode Blip', 'None', blip)]
	for bchil in blip.child_blips:
		data += getChildBlipIds(bchil)
	return [(blip, blip.creator, blip.text[:20])] + data



if __name__ == '__main__':
	myRobot = robot.Robot('Forensie', 
		image_url='http://forensie.appspot.com/assets/hdd_head1.jpg',
		profile_url='http://code.google.com/p/forensie/')
	myRobot.register_handler(events.BlipSubmitted, OnBlipSubmitted, context=[events.Context.ALL])
	myRobot.register_handler(events.WaveletSelfAdded, OnWaveletSelfAdded)
	appengine_robot_runner.run(myRobot)